home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / cyberqt / txt / cyberqtsync.mod < prev    next >
Text File  |  1999-02-08  |  9KB  |  290 lines

  1. MODULE CyberQTSync;
  2.  
  3. (* $IFNOT DEBUG *)
  4.   (* $StackChk- $OvflChk- $RangeChk- $CaseChk- $ReturnChk- $NilChk- $TypeChk- $OddChk- $ClearVars- *)
  5. (* $END *)
  6.  
  7. (* /// ------------------------------- "IMPORT" -------------------------------- *)
  8. IMPORT  cu:=CyberQTUtils,
  9.         d:=Dos,
  10.         e:=Exec,
  11.         g:=CyberQTGlobals,
  12.         m:=MathFFP,
  13.         mu:=MathUtils,
  14.         o:=CyberQTOpts,
  15.         t:=Timer,
  16.         y:=SYSTEM;
  17. (* \\\ ------------------------------------------------------------------------- *)
  18.  
  19. (* /// --------------------------------- "VAR" --------------------------------- *)
  20. VAR     timerPort: e.MsgPortPtr;
  21.         timerOpen: BOOLEAN;
  22.         timerSig - : LONGINT;
  23.         timerIO: t.TimeRequestPtr;
  24.         nextTime: t.EClockVal;
  25.         frameTime: t.EClockVal;
  26.         syncTime: t.EClockVal;
  27.         oneSecond: t.EClockVal;
  28.         microsPerEClock: REAL;
  29.         start: t.EClockVal;
  30.         stop: t.EClockVal;
  31.         speedChanged - : BOOLEAN;
  32.         speedFactor: REAL;
  33. (* \\\ ------------------------------------------------------------------------- *)
  34.  
  35. (* /// --------------------- "PROCEDURE Micros2EClocks()" ---------------------- *)
  36. PROCEDURE Micros2EClocks(micros: LONGINT): LONGINT;
  37. BEGIN
  38.   RETURN mu.floor(micros/microsPerEClock);
  39. END Micros2EClocks;
  40. (* \\\ ------------------------------------------------------------------------- *)
  41.  
  42. (* /// --------------------- "PROCEDURE GetPlayingTime()" ---------------------- *)
  43. PROCEDURE GetPlayingTime(): REAL;
  44.  
  45. VAR     time: LONGINT;
  46.         track: g.TrackPtr;
  47.  
  48. BEGIN
  49.   time:=0;
  50.   track:=g.animInfo.videoTracks.head;
  51.   WHILE track.node.succ#NIL DO
  52.     time:=mu.max(time,track.head.duration);
  53.     track:=track.node.succ;
  54.   END;
  55.   RETURN mu.min(g.animInfo.mvhd.duration,time)/g.animInfo.mvhd.timeScale;
  56. END GetPlayingTime;
  57. (* \\\ ------------------------------------------------------------------------- *)
  58.  
  59. (* /// ------------------------- "PROCEDURE DoStats()" ------------------------- *)
  60. PROCEDURE DoStats * (framesDone: LONGINT;
  61.                      framesSkipped: LONGINT;
  62.                      totalFrames: LONGINT);
  63.  
  64. VAR     fps: REAL;
  65.         time: REAL;
  66.         realFPS: e.STRING;
  67.         realTime: e.STRING;
  68.         expFPS: e.STRING;
  69.         expTime: e.STRING;
  70.         diff: REAL;
  71.         diffS: e.STRING;
  72.  
  73. BEGIN
  74.   mu.Sub64(stop,start);
  75.  
  76.   time:=((stop.hi*4294967296.0+stop.lo)*microsPerEClock)/1000000;
  77.   fps:=framesDone/time;
  78.   diff:=time;
  79.   mu.real2str(time,realTime,6);
  80.   mu.real2str(fps,realFPS,2);
  81.  
  82.   time:=GetPlayingTime();
  83.   fps:=totalFrames/time;
  84.   mu.real2str(time,expTime,6);
  85.   mu.real2str(fps,expFPS,2);
  86.  
  87.   mu.real2str(diff-time,diffS,6);
  88.  
  89.   d.PrintF("\n"
  90.            "Statistics:\n"
  91.            "  total frames    : %4ld\n"
  92.            "  frames processed: %4ld\n"
  93.            "  frames displayed: %4ld\n"
  94.            "  frames skipped  : %4ld\n"
  95.            "  real time used  : %11s seconds (%6s fps)\n"
  96.            "  expected time   : %11s seconds (%6s fps)\n"
  97.            "  difference      : %11s seconds\n"
  98.            "\n",totalFrames,
  99.                 framesDone,
  100.                 framesDone-framesSkipped,
  101.                 framesSkipped,
  102.                 y.ADR(realTime),y.ADR(realFPS),
  103.                 y.ADR(expTime),y.ADR(expFPS),
  104.                 y.ADR(diffS));
  105. END DoStats;
  106. (* \\\ ------------------------------------------------------------------------- *)
  107.  
  108. (* /// ----------------------- "PROCEDURE CloseTimer()" ------------------------ *)
  109. PROCEDURE CloseTimer();
  110. BEGIN
  111.   IF timerOpen THEN
  112.     IF e.CheckIO(timerIO)=NIL THEN (* es läuft noch ein Request *)
  113.       e.AbortIO(timerIO);
  114.       y.SETREG(0,e.WaitIO(timerIO));
  115.     END;
  116.     e.CloseDevice(timerIO);
  117.   END;
  118.   IF timerIO#NIL THEN e.DeleteIORequest(timerIO); END;
  119.   IF timerPort#NIL THEN e.DeleteMsgPort(timerPort); END;
  120. END CloseTimer;
  121. (* \\\ ------------------------------------------------------------------------- *)
  122.  
  123. (* /// ------------------------ "PROCEDURE OpenTimer()" ------------------------ *)
  124. PROCEDURE OpenTimer(): BOOLEAN;
  125.  
  126. VAR     now: t.EClockVal;
  127.  
  128. BEGIN
  129.   timerOpen:=FALSE;
  130.   timerIO:=NIL;
  131.   timerPort:=e.CreateMsgPort();
  132.   IF timerPort=NIL THEN
  133.     d.PrintF("Can't create timer message port!\n");
  134.     RETURN FALSE;
  135.   END;
  136.   timerSig:=timerPort.sigBit;
  137.   timerIO:=e.CreateIORequest(timerPort,SIZE(timerIO^));
  138.   IF timerIO=NIL THEN
  139.     d.PrintF("Can't create timer iorequest!\n");
  140.     RETURN FALSE;
  141.   END;
  142.   timerOpen:=(e.OpenDevice(t.timerName,t.waitEClock,timerIO,LONGSET{})=0);
  143.   IF ~timerOpen THEN
  144.     d.PrintF("Can't open timer.device!\n");
  145.     RETURN FALSE;
  146.   END;
  147.   timerIO.node.command:=t.addRequest;
  148.   t.base:=timerIO.node.device;
  149.   microsPerEClock:=1000000.0/t.ReadEClock(now);
  150.   oneSecond.hi:=0;
  151.   oneSecond.lo:=Micros2EClocks(1000000);
  152.   RETURN TRUE;
  153. END OpenTimer;
  154. (* \\\ ------------------------------------------------------------------------- *)
  155.  
  156. (* /// -------------------------- "PROCEDURE Wait()" --------------------------- *)
  157. PROCEDURE Wait * (secs: LONGINT);
  158.  
  159. VAR     now: t.EClockVal;
  160.         until: t.EClockVal;
  161.  
  162. BEGIN
  163.   until.hi:=0;
  164.   until.lo:=Micros2EClocks(secs*1000000);
  165.   y.SETREG(0,t.ReadEClock(now));
  166.   mu.Add64(until,now);
  167.   timerIO.time:=y.VAL(t.TimeVal,until);
  168.   y.SETREG(0,e.DoIO(timerIO));
  169. END Wait;
  170. (* \\\ ------------------------------------------------------------------------- *)
  171.  
  172. (* /// ----------------------- "PROCEDURE StartTimer()" ------------------------ *)
  173. PROCEDURE StartTimer * ();
  174. BEGIN
  175.   IF o.maxFPS THEN
  176.     speedChanged:=TRUE;
  177.     speedFactor:=0.0;
  178.   ELSE
  179.     speedChanged:=FALSE;
  180.     speedFactor:=1.0;
  181.   END;
  182.   frameTime:=t.EClockVal(0,0);
  183.   y.SETREG(0,t.ReadEClock(start));
  184.   nextTime:=start;
  185.   syncTime:=start;
  186.   mu.Add64(syncTime,oneSecond);
  187.   timerIO.time:=y.VAL(t.TimeVal,nextTime);
  188.   e.SendIO(timerIO);
  189. END StartTimer;
  190. (* \\\ ------------------------------------------------------------------------- *)
  191.  
  192. (* /// ------------------------ "PROCEDURE StopTimer()" ------------------------ *)
  193. PROCEDURE StopTimer();
  194. BEGIN
  195.   y.SETREG(0,t.ReadEClock(stop));
  196. END StopTimer;
  197. (* \\\ ------------------------------------------------------------------------- *)
  198.  
  199. (* /// ----------------------- "PROCEDURE PauseTimer()" ------------------------ *)
  200. PROCEDURE PauseTimer * (pause: BOOLEAN);
  201.  
  202. VAR     temp: t.EClockVal;
  203.         now: t.EClockVal;
  204.  
  205. BEGIN
  206.   IF pause THEN
  207.     temp:=nextTime;
  208.     y.SETREG(0,t.ReadEClock(now));
  209.     mu.Sub64(temp,now);
  210.     frameTime:=temp;
  211.     nextTime:=now;
  212.     WHILE e.CheckIO(timerIO)=NIL DO
  213.       e.AbortIO(timerIO);
  214.       y.SETREG(0,e.WaitIO(timerIO));
  215.     END;
  216.   ELSE
  217.     y.SETREG(0,t.ReadEClock(nextTime));
  218. (*
  219.     mu.Add64(nextTime,frameTime);
  220. *)
  221.     syncTime:=nextTime;
  222.     frameTime.hi:=0;
  223.     timerIO.time:=y.VAL(t.TimeVal,nextTime);
  224.     e.SendIO(timerIO);
  225.   END;
  226. END PauseTimer;
  227. (* \\\ ------------------------------------------------------------------------- *)
  228.  
  229. (* /// --------------------- "PROCEDURE SetSpeedFactor()" ---------------------- *)
  230. PROCEDURE SetSpeedFactor * (factor: REAL);
  231. BEGIN
  232.   IF e.CheckIO(timerIO)=NIL THEN
  233.     e.AbortIO(timerIO);
  234.     y.SETREG(0,e.WaitIO(timerIO));
  235.   END;
  236.   y.SETREG(0,t.ReadEClock(nextTime));
  237.   speedFactor:=factor;
  238.   speedChanged:=(speedFactor#1.0);
  239. END SetSpeedFactor;
  240. (* \\\ ------------------------------------------------------------------------- *)
  241.  
  242. (* /// ---------------------- "PROCEDURE DoFrameDelay()" ----------------------- *)
  243. PROCEDURE DoFrameDelay * (time: REAL;
  244.                           skipping: BOOLEAN);
  245. BEGIN
  246.   frameTime.lo:=mu.floor((time*1000000*speedFactor)/microsPerEClock);
  247.   mu.Add64(nextTime,frameTime);
  248.   IF ~skipping THEN timerIO.time:=y.VAL(t.TimeVal,nextTime); END;
  249.   e.SendIO(timerIO);
  250. END DoFrameDelay;
  251. (* \\\ ------------------------------------------------------------------------- *)
  252.  
  253. (* /// ------------------------- "PROCEDURE IsSync()" -------------------------- *)
  254. PROCEDURE IsSync * (): BOOLEAN;
  255.  
  256. VAR     now: t.EClockVal;
  257.         ret: BOOLEAN;
  258.  
  259. BEGIN
  260.   IF speedChanged THEN
  261.     ret:=TRUE; (* falls Geschwindigkeit geändert, dann immer synchron *)
  262.   ELSE
  263.     y.SETREG(0,t.ReadEClock(now));
  264.     mu.Sub64(now,frameTime); (* synctime>=now-frametime? *)
  265.     ret:=(mu.Cmp64(syncTime,now)<=0); (* syncTime ist noch später als now => synchron *)
  266.   END;
  267.   IF mu.Cmp64(syncTime,nextTime)>=0 THEN mu.Add64(syncTime,oneSecond); END; (* eine Sekunde ist vorbei, syncTime aktualisieren *)
  268.   RETURN ret;
  269. END IsSync;
  270. (* \\\ ------------------------------------------------------------------------- *)
  271.  
  272. (* /// --------------------- "PROCEDURE Wait4LastFrame()" ---------------------- *)
  273. PROCEDURE Wait4LastFrame * ();
  274. BEGIN
  275.   IF e.CheckIO(timerIO)=NIL THEN
  276.     y.SETREG(0,e.Wait(LONGSET{timerSig})); (* auf Timer warten, sonst wird der letzte Frame zu kurz dargestellt *)
  277.   END;
  278.   StopTimer();
  279. END Wait4LastFrame;
  280. (* \\\ ------------------------------------------------------------------------- *)
  281.  
  282. BEGIN
  283.   IF ~OpenTimer() THEN
  284.     d.PrintF("Can't open timer!\n");
  285.     HALT(0);
  286.   END;
  287. CLOSE
  288.   CloseTimer();
  289. END CyberQTSync.
  290.